﻿using System;
using System.Collections.Generic;
using System.Linq;
using EasySite.Models;

namespace EasySite.Services.Implementations
{
    public class PageCategoryService : ServiceBase, IPageCategoryService
    {
        #region Implementation of IPageCategoryService

        public List<PageCategory> GetPageCategories()
        {
            var query = from category in DataContext.PageCategories
                        join x in DataContext.PageCategoryInRoles on category.ID equals x.PageCategoryID
                            into relations
                        from inRole in relations.DefaultIfEmpty()
                        where category.Deleted == false
                        select new
                                   {
                                       category.ID,
                                       category.DisplayText,
                                       category.Name,
                                       category.NeedAuthentication,
                                       category.ParentID,
                                       category.Sequence,
                                       Role = inRole.Role.Name
                                   };
            var items = query.ToList();
            var groupedItems = items.GroupBy(m => m.ID);
            var allCategories = new List<PageCategory>();
            foreach (var groupedDto in groupedItems)
            {
                var roles = groupedDto.Where(m => !string.IsNullOrEmpty(m.Role)).Select(m => m.Role);
                var defaultCategory = items.First(m => m.ID == groupedDto.Key);
                var category = new PageCategory()
                                   {
                                       ID = defaultCategory.ID,
                                       DisplayText = defaultCategory.DisplayText,
                                       Name = defaultCategory.Name,
                                       NeedAuthentication = defaultCategory.NeedAuthentication,
                                       ParentID = defaultCategory.ParentID,
                                       Sequence = defaultCategory.Sequence,
                                       Roles = roles.ToArray()
                                   };
                allCategories.Add(category);
            }
            var categories = allCategories.Where(m => m.ParentID == null).OrderBy(m => m.Sequence).ToList();
            categories.ForEach(c => FillCategoryChildren(c, allCategories));
            return categories;
        }

        #endregion

        #region private methods

        private static void FillCategoryChildren(PageCategory parent, IEnumerable<PageCategory> allCategories)
        {
            var children = allCategories.Where(c => c.ParentID != null && c.ParentID == parent.ID).ToList();
            if (children.Count == 0)
            {
                return;
            }
            parent.Children.AddRange(children.OrderBy(m => m.Sequence));
            foreach (var child in children)
            {
                FillCategoryChildren(child, allCategories);
            }
        }

        #endregion
    }
}
